import FUtils from 'fo-utils';
import Marker from "./Marker";

class Map {
    /**
     * 初始化安装AMap
     * @param AMap
     */
    static install(AMap) {
        Map.AMap = AMap;
        Marker.install(AMap);
    }

    constructor(map, dom) {
        this.map = map;
        this.dom = dom;
        this.__markers__ = {};
        this.__markerIndex__ = 0;
        this.__componentsCache__ = {};
    }

    /**
     * 标记一个点
     * @param lng 经度
     * @param lat 维度
     * @param title 标题
     * @returns {Marker} 点对象
     */
    mark(lng, lat, title) {
        if (title === undefined || title === null) {
            throw new Error('The arg of title cannot be undefined or null.');
        }
        let m = new Map.AMap.Marker({
            position: new Map.AMap.LngLat(lng, lat),
            title: title,
        });
        this.map.add(m);
        let index = this._getMarkerIndex();
        let result = new Marker(m, title, this, index);
        this.__markers__[index] = result;
        return result;
    }

    /**
     * 移除标记
     * @param index 序号
     */
    unmark(index) {
        if (FUtils.NumberUtils.isNumber(index)) {
            this.map.remove(this.__markers__[index].marker);
            delete this.__markers__[index];
        }
    }

    /**
     * 移除所有标记
     */
    unmarkAll() {
        Object.keys(this.__markers__).forEach(key => {
            this.map.remove(this.__markers__[key].marker);
            delete this.__markers__[key];
        });
    }

    addBasicControl(type, option = {
        //left top，左上角
        position: 'lt'
    }) {
        if (!Map.ui.BasicControl) {
            throw new Error("The component[BasicControl] of ui hasn't been loaded!");
        }

        let _type = type.toLowerCase();
        if (this.__componentsCache__['basic_' + _type]) {
            throw new Error("The component[" + type + " of BasicControl] already added!");
        }
        let cache = null;
        switch (_type) {
            case 'zoom':
                cache = new Map.ui.BasicControl.Zoom(option);
                break;
            case 'layerswitcher':
                cache = new Map.ui.BasicControl.LayerSwitcher(option);
                break;
            case 'traffic':
                cache = new Map.ui.BasicControl.Traffic(option);
                break;
            default:
                return;
        }
        cache.addTo(this.map);
        this.__componentsCache__['basic_' + _type] = cache;
    }

    removeBasicControl(type) {
        let _type = type.toLowerCase();
        this.__removeControl('basic_' + _type);
    }

    addGeolocation(option = {
        // 是否使用高精度定位，默认：true
        enableHighAccuracy: true,
        // 设置定位超时时间，默认：无穷大
        timeout: 10000,
        // 定位按钮的停靠位置的偏移量，默认：Pixel(10, 20)
        buttonOffset: new Map.AMap.Pixel(10, 20),
        //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
        zoomToAccuracy: true,
        //  定位按钮的排放位置,  RB表示右下
        buttonPosition: 'RB'
    }) {
        if (!Map.plugin.Geolocation) {
            throw new Error("The component[Geolocation] of ui hasn't been loaded!");
        }
        let geolocation = new Map.plugin.Geolocation(option);
        this.__componentsCache__['geolocation'] = geolocation;
        this.map.addControl(geolocation);
        // geolocation.addTo(this.map);
        return new Promise((resolve, reject) => {
            geolocation.getCurrentPosition((status, result) => {
                if (status === 'complete') {
                    resolve(result);
                } else {
                    reject(result);
                }
            })
        });

    }

    removeGeolocation() {
        this.__removeControl('geolocation');
    }

    __removeControl(component) {
        if (this.__componentsCache__[component]) {
            this.map.removeControl(this.__componentsCache__[component]);
            delete this.__componentsCache__[component];
        }
    }

    /**
     * 设置合适视图
     */
    setFitView() {
        this.map.setFitView();
    }

    /**
     * 获取当前标记序号
     * @returns {number}
     */
    _getMarkerIndex() {
        this.__markerIndex__++;
        return this.__markerIndex__ - 1;
    }
}

Map.ui = {};
Map.plugin = {};
Map.AMap = null;
export default Map;